package org.dromara.hm.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.json.utils.JsonUtils;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.hm.domain.HmSaleOrder;
import org.dromara.hm.domain.HmSaleOrderPickUp;
import org.dromara.hm.domain.bo.HmPickupRequestBo;
import org.dromara.hm.domain.bo.HmSaleOrderGiftBo;
import org.dromara.hm.domain.bo.HmSaleOrderPickUpBo;
import org.dromara.hm.domain.bo.HmSaleOrderRefundBo;
import org.dromara.hm.domain.bo.HmStockBo;
import org.dromara.hm.domain.bo.HmStockChangeBo;
import org.dromara.hm.domain.bo.HmSupplementaryPickupRecordBo;
import org.dromara.hm.domain.vo.HmCustomerVo;
import org.dromara.hm.domain.vo.HmProductVo;
import org.dromara.hm.domain.vo.HmStockVo;
import org.dromara.hm.domain.vo.saleOrder.HmSaleOrderGiftVo;
import org.dromara.hm.domain.vo.saleOrder.HmSaleOrderPickUpVo;
import org.dromara.hm.domain.vo.saleOrder.HmSaleOrderVo;
import org.dromara.hm.domain.vo.saleOrder.HmSupplementaryPickupRecordVo;
import org.dromara.hm.domain.vo.saleOrder.OrderProductQuantities;
import org.dromara.hm.enums.OrderStatus;
import org.dromara.hm.enums.PickUpStatusEnum;
import org.dromara.hm.enums.StockChangeTypeEnum;
import org.dromara.hm.enums.StockTypeEnum;
import org.dromara.hm.mapper.HmCustomerMapper;
import org.dromara.hm.mapper.saleOrder.HmSaleOrderMapper;
import org.dromara.hm.mapper.saleOrder.HmSaleOrderPickUpMapper;
import org.dromara.hm.service.IHmProductService;
import org.dromara.hm.service.IHmSaleOrderGiftService;
import org.dromara.hm.service.IHmSaleOrderPickUpService;
import org.dromara.hm.service.IHmSaleOrderRefundService;
import org.dromara.hm.service.IHmStockChangeService;
import org.dromara.hm.service.IHmStockService;
import org.dromara.hm.service.IHmSupplementaryPickupRecordService;
import org.dromara.hm.service.IHmTodoItemsService;
import org.dromara.hm.util.OrderProductCalculator;
import org.dromara.system.service.ISysDeptService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.DoubleStream;

/**
 * 销售订单提货、回款Service业务层处理
 *
 * @author Hzy
 * @date 2025-01-06
 */
@RequiredArgsConstructor
@Service
public class HmSaleOrderPickUpServiceImpl implements IHmSaleOrderPickUpService
{

    private final HmSaleOrderPickUpMapper baseMapper;

    private final IHmStockService hmStockService;

    private final HmSaleOrderMapper hmSaleOrderMapper;

    private final IHmSaleOrderGiftService hmSaleOrderGiftService;

    private final IHmStockChangeService hmStockChangeService;

    private final IHmSaleOrderRefundService hmSaleOrderRefundService;

    private final ISysDeptService deptService;

    private final IHmTodoItemsService hmTodoItemsService;

    private final IHmProductService hmProductService; // 注入产品Service

    private final IHmSupplementaryPickupRecordService supplementaryPickupRecordService;

    private final OrderProductCalculator orderProductCalculator; // 注入 OrderProductCalculator

    private final HmCustomerMapper customerMapper; // 注入 OrderProductCalculator

    /**
     * 新增销售订单提货、回款
     *
     * @param bo       销售订单提货、回款新增
     *                 <p>
     *                 /**
     *                 查询销售订单提货、回款
     * @param pickUpId 主键
     *
     * @return 销售订单提货、回款
     */
    @Override
    public HmSaleOrderPickUpVo queryById(Long pickUpId)
    {
        return baseMapper.selectVoById(pickUpId);
    }

    /**
     * 分页查询销售订单提货、回款列表
     *
     * @param bo        查询条件
     * @param pageQuery 分页参数
     *
     * @return 销售订单提货、回款分页列表
     */
    @Override
    public TableDataInfo<HmSaleOrderPickUpVo> queryPageList(HmSaleOrderPickUpBo bo, PageQuery pageQuery)
    {
        List<HmSaleOrderPickUpVo> combinedList = new ArrayList<>();
        long total = 0;

        // 获取原始提货/回款记录的查询条件
        LambdaQueryWrapper<HmSaleOrderPickUp> normalLqw = buildQueryWrapper(bo);

        // 根据 productType 参数判断查询逻辑
        if (StringUtils.isNotBlank(bo.getProductType()))
        {
            if ("CP".equalsIgnoreCase(bo.getProductType()))
            {
                // 情况1: 查询商品产品 (CP) 的提货记录，并包含补充提货记录和回款记录
                // a. 查询正常的商品产品提货记录
                normalLqw.eq(HmSaleOrderPickUp::getPickUpType, OrderStatus.PICK_UP.getCode()); // 确保是提货类型
                normalLqw.apply("EXISTS (SELECT 1 FROM hm_product p WHERE p.product_id = hm_sale_order_pick_up.sale_product_id AND p.is_commercial_product = TRUE)");
                List<HmSaleOrderPickUpVo> normalCpPickups = baseMapper.selectVoList(normalLqw);
                normalCpPickups.forEach(record -> record.setIsSupplementaryPickup(false)); // 标记为非补充提货
                combinedList.addAll(normalCpPickups);

                // b. 查询商品产品的补充提货记录
                List<HmSaleOrderPickUpVo> supplementaryCpPickups = baseMapper.selectSupplementaryPickupsAsNormalPickups(bo.getSaleOrderId(), true, false); // originalSaleId, isCommercialProduct=true, isGiftProduct=false
                combinedList.addAll(supplementaryCpPickups);

                // c. 查询回款记录 (回款通常是针对商品订单，不区分具体商品)
                // 仅当查询条件中没有指定提货类型时，才包含回款记录，避免重复或逻辑冲突
                if (StringUtils.isBlank(bo.getPickUpType()) || OrderStatus.RETURN_MONEY.getCode().equals(bo.getPickUpType()))
                {
                    LambdaQueryWrapper<HmSaleOrderPickUp> paymentLqw = Wrappers.lambdaQuery();
                    paymentLqw.eq(bo.getSaleOrderId() != null, HmSaleOrderPickUp::getSaleOrderId, bo.getSaleOrderId());
                    paymentLqw.eq(HmSaleOrderPickUp::getPickUpType, OrderStatus.RETURN_MONEY.getCode()); // 回款类型
                    paymentLqw.eq(StringUtils.isNotBlank(bo.getStatus()), HmSaleOrderPickUp::getStatus, bo.getStatus());
                    paymentLqw.between(bo.getStartTime() != null && bo.getEndTime() != null, HmSaleOrderPickUp::getPickUpTime, bo.getStartTime(), bo.getEndTime());
                    // 回款记录不直接关联 product_id，所以这里不加产品类型过滤，除非您的业务逻辑要求回款也按产品类型过滤
                    List<HmSaleOrderPickUpVo> paymentRecords = baseMapper.selectVoList(paymentLqw);
                    paymentRecords.forEach(record -> record.setIsSupplementaryPickup(false)); // 标记为非补充提货
                    combinedList.addAll(paymentRecords);
                }

            }
            else if ("ZP".equalsIgnoreCase(bo.getProductType()))
            {
                // 情况2: 查询赠品产品 (ZP) 的提货记录，按照最初的逻辑执行 (只查询正常的提货记录，不包含补充提货)
                normalLqw.eq(HmSaleOrderPickUp::getPickUpType, OrderStatus.PICK_UP.getCode()); // 确保是提货类型
                normalLqw.apply("EXISTS (SELECT 1 FROM hm_product p WHERE p.product_id = hm_sale_order_pick_up.sale_product_id AND p.is_gift_product = TRUE)");
                List<HmSaleOrderPickUpVo> normalZpPickups = baseMapper.selectVoList(normalLqw);
                normalZpPickups.forEach(record -> record.setIsSupplementaryPickup(false)); // 标记为非补充提货
                combinedList.addAll(normalZpPickups);

                // 根据您的要求，当查询赠品时，不返回补充提货记录，所以这里移除了 supplementaryZpPickups 的查询和添加
                // 如果将来业务需求变化，赠品也需要显示补充提货，则可以取消注释下方代码

                List<HmSaleOrderPickUpVo> supplementaryZpPickups = baseMapper.selectSupplementaryPickupsAsNormalPickups(bo.getSaleOrderId(), false, true); // originalSaleId, isCommercialProduct=false, isGiftProduct=true
                combinedList.addAll(supplementaryZpPickups);

            }
            else
            {
                // 未知产品类型，或者 productType 为空，查询所有正常提货/回款记录
                // buildQueryWrapper 已经包含了 productType 的过滤，这里直接调用
                List<HmSaleOrderPickUpVo> allNormalPickups = baseMapper.selectVoList(normalLqw);
                allNormalPickups.forEach(record -> record.setIsSupplementaryPickup(false));
                combinedList.addAll(allNormalPickups);

                // 此时，如果需要显示所有类型的补充提货记录，也需要查询并合并
                // 暂时不包含在此处，因为productType为空的情况，业务逻辑没有明确说明是否包含所有补充提货
                // 如果需要，可以添加类似商品产品的补充提货查询
                /*
                List<HmSaleOrderPickUpVo> allSupplementaryPickups = baseMapper.selectSupplementaryPickupsAsNormalPickups(
                    bo.getSaleOrderId(), null, null); // 查询所有类型的补充提货
                combinedList.addAll(allSupplementaryPickups);
                */
            }
        }
        else
        {
            // 情况3: productType 为空，按照最初的逻辑执行，查询所有正常提货/回款记录
            // buildQueryWrapper 已经不包含 productType 的过滤，这里直接调用
            List<HmSaleOrderPickUpVo> allNormalPickups = baseMapper.selectVoList(normalLqw);
            allNormalPickups.forEach(record -> record.setIsSupplementaryPickup(false));
            combinedList.addAll(allNormalPickups);

            // 此时，如果需要显示所有类型的补充提货记录，也需要查询并合并
            // 暂时不包含在此处，因为productType为空的情况，业务逻辑没有明确说明是否包含所有补充提货
            // 如果需要，可以添加类似商品产品的补充提货查询
            /*
            List<HmSaleOrderPickUpVo> allSupplementaryPickups = baseMapper.selectSupplementaryPickupsAsNormalPickups(
                bo.getSaleOrderId(), null, null); // 查询所有类型的补充提货
            combinedList.addAll(allSupplementaryPickups);
            */
        }

        // 3. 对合并后的列表进行排序和分页
        // 确保 pickUpTime 字段不为 null，以便排序
        combinedList.sort(Comparator.comparing(HmSaleOrderPickUpVo::getPickUpTime, Comparator.nullsLast(Comparator.naturalOrder())).reversed());

        total = combinedList.size();
        IPage<HmSaleOrderPickUpVo> page = pageQuery.build();
        page.setTotal(total);
        // 手动分页 set数据
        page.setRecords(CollUtil.page((int) page.getCurrent() - 1, (int) page.getSize(), combinedList));
        return TableDataInfo.build(page);
    }

    /**
     * 查询符合条件的销售订单提货、回款列表
     *
     * @param bo 查询条件
     *
     * @return 销售订单提货、回款列表
     */
    @Override
    public List<HmSaleOrderPickUpVo> queryList(HmSaleOrderPickUpBo bo)
    {
        LambdaQueryWrapper<HmSaleOrderPickUp> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<HmSaleOrderPickUp> buildQueryWrapper(HmSaleOrderPickUpBo bo)
    {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<HmSaleOrderPickUp> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getSaleOrderId() != null, HmSaleOrderPickUp::getSaleOrderId, bo.getSaleOrderId());
        lqw.between(bo.getStartTime() != null && bo.getEndTime() != null, HmSaleOrderPickUp::getPickUpTime, bo.getStartTime(), bo.getEndTime());
        lqw.eq(StringUtils.isNotBlank(bo.getPickUpType()), HmSaleOrderPickUp::getPickUpType, bo.getPickUpType());
        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), HmSaleOrderPickUp::getStatus, bo.getStatus());
        lqw.eq(bo.getSaleProductId() != null, HmSaleOrderPickUp::getSaleProductId, bo.getSaleProductId());
        return lqw;
    }

    //    /**
    //     * 提交 提货/回款 业务 (旧方法，现在由 insertByPickupRequest 统一处理)
    //     *
    //     * @param bo 业务实体
    //     *
    //     * @return 是否提交成功
    //     */
    //    @Transactional(rollbackFor = Exception.class)
    //    public Boolean insertByBo(HmSaleOrderPickUpBo bo)
    //    {
    //        HmSaleOrderPickUp add = MapstructUtils.convert(bo, HmSaleOrderPickUp.class);
    //        if (add != null)
    //        {
    //            // 获取产品类型信息
    //            Boolean isCommercialProduct = hmProductService.isCommercialProduct(bo.getSaleProductId());
    //            Boolean isGiftProduct = hmProductService.isGiftProduct(bo.getSaleProductId());
    //
    //            if (OrderStatus.PICK_UP.getCode().equals(add.getPickUpType())) // 提货
    //            {
    //                if (Boolean.TRUE.equals(isGiftProduct)) // 如果是赠品产品
    //                {
    //                    if (bo.getSaleProductId() != null)
    //                    {
    //                        add.setSaleProductId(bo.getSaleProductId()); // 确保这里是正确的赠品产品ID
    //                    }
    //                    else
    //                    {
    //                        throw new RuntimeException("提货失败，请查看是否正确选择待提货赠品！");
    //                    }
    //                } else if (Boolean.FALSE.equals(isCommercialProduct)) { // 既不是商品也不是赠品，或者只是赠品但这里处理的是商品提货
    //                    throw new RuntimeException("提货失败，所选产品不是商品产品类型！");
    //                }
    //                // 处理提货逻辑
    //                return handlePickUpLogic(add);
    //            }
    //            else if (OrderStatus.RETURN_MONEY.getCode().equals(add.getPickUpType())) // 回款
    //            {
    //                // 处理回款逻辑
    //                return handlePaymentLogic(add);
    //            }
    //        }
    //        return false;
    //    }

    /**
     * 根据统一提货请求新增提货记录 (支持多项提货和补充提货)
     *
     * @param requestBo 提货请求业务对象
     *
     * @return 是否新增成功
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean insertByPickupRequest(HmPickupRequestBo requestBo)
    {
        if (requestBo == null || requestBo.getOrderId() == null || ObjectUtil.isEmpty(requestBo.getItems()))
        {
            throw new ServiceException("提货请求或订单ID或提货项列表不能为空。");
        }

        // 获取当前订单信息，用于校验和填充冗余字段
        HmSaleOrderVo saleOrder = hmSaleOrderMapper.selectVoById(requestBo.getOrderId());
        if (saleOrder == null)
        {
            throw new ServiceException("销售订单不存在。");
        }

        // 查询当前订单的赠品集合
        HmSaleOrderGiftBo hmSaleOrderGiftBo = new HmSaleOrderGiftBo();
        hmSaleOrderGiftBo.setSaleId(saleOrder.getSaleId());
        List<HmSaleOrderGiftVo> hmSaleOrderGiftVos = hmSaleOrderGiftService.queryList(hmSaleOrderGiftBo);
        saleOrder.setGiftList(hmSaleOrderGiftVos);

        // 获取操作人信息
        Long operatorId = LoginHelper.getUserId();
        String operatorName = LoginHelper.getLoginUser().getNickname();
        Long operatorDeptId = LoginHelper.getDeptId(); // 操作人所在店铺

        boolean allSuccess = true;

        for (HmPickupRequestBo.PickupItemBo item : requestBo.getItems())
        {
            try
            {
                // 校验产品ID和数量
                if (item.getProductId() == null || item.getQuantity() == null || item.getQuantity().compareTo(BigDecimal.ZERO) <= 0)
                {
                    throw new ServiceException("提货项产品ID或数量无效。");
                }

                // 获取产品信息
                HmProductVo productVo = hmProductService.queryById(item.getProductId());
                if (productVo == null)
                {
                    throw new ServiceException("产品ID: " + item.getProductId() + " 不存在。");
                }


                // 校验产品类别 (product/gift) 与实际产品类型 (CP/ZP) 是否一致
                Boolean isCommercialProduct = hmProductService.isCommercialProduct(item.getProductId());
                Boolean isGiftProduct = hmProductService.isGiftProduct(item.getProductId());

                if ("product".equalsIgnoreCase(item.getType()))
                { // 期望是商品产品
                    if (Boolean.FALSE.equals(isCommercialProduct))
                    {
                        throw new ServiceException("产品ID: " + item.getProductId() + " 不是商品产品类型，但请求类别为商品。");
                    }
                }
                else if ("gift".equalsIgnoreCase(item.getType()))
                { // 期望是赠品产品
                    if (Boolean.FALSE.equals(isGiftProduct))
                    {
                        throw new ServiceException("产品ID: " + item.getProductId() + " 不是赠品产品类型，但请求类别为赠品。");
                    }
                }
                else
                {
                    throw new ServiceException("无效的产品类别: " + item.getType());
                }
                String file = requestBo.getAttachments().stream().collect(Collectors.joining(","));
                if ("normal".equalsIgnoreCase(requestBo.getType()))
                {
                    // 处理正常提货
                    HmSaleOrderPickUp add = new HmSaleOrderPickUp();
                    add.setSaleOrderId(requestBo.getOrderId());
                    add.setSaleProductId(item.getProductId());
                    add.setPickUpNum(item.getQuantity());
                    add.setPickUpTime(new Date());
                    add.setFile(file); // 附件
                    add.setPickUpType(OrderStatus.PICK_UP.getCode()); // 提货类型
                    add.setProductType("product".equalsIgnoreCase(item.getType()) ? "CP" : "ZP"); // 存储实际产品类型
                    add.setStatus(PickUpStatusEnum.NORMAL.getCode());
                    add.setRemark(requestBo.getRemark());
                    // 调用现有逻辑处理单项提货
                    handlePickUpLogic(add);

                }
                else if ("supplementary".equalsIgnoreCase(requestBo.getType()))
                {
                    // 处理补充提货
                    if (item.getOriginalProductId() == null)
                    {
                        throw new ServiceException("补充提货必须指定原始产品ID。");
                    }
                    HmProductVo originalProductVo = hmProductService.queryById(item.getOriginalProductId());
                    if (originalProductVo == null)
                    {
                        throw new ServiceException("原始产品ID: " + item.getOriginalProductId() + " 不存在。");
                    }

                    // 校验原始产品和补充产品类型一致性
                    Boolean isOriginalCommercial = hmProductService.isCommercialProduct(item.getOriginalProductId());
                    Boolean isOriginalGift = hmProductService.isGiftProduct(item.getOriginalProductId()); // 修正：使用 item.getOriginalProductId()
                    Boolean isSupplementaryCommercial = hmProductService.isCommercialProduct(item.getProductId());
                    Boolean isSupplementaryGift = hmProductService.isGiftProduct(item.getProductId());

                    if (Boolean.TRUE.equals(isOriginalCommercial) && Boolean.FALSE.equals(isSupplementaryCommercial))
                    {
                        throw new ServiceException("补充提货失败：商品产品只能用商品产品进行补充。");
                    }
                    if (Boolean.TRUE.equals(isOriginalGift) && Boolean.FALSE.equals(isSupplementaryGift))
                    {
                        throw new ServiceException("补充提货失败：赠品产品只能用赠品产品进行补充。");
                    }
                    if (Boolean.FALSE.equals(isOriginalCommercial) && Boolean.FALSE.equals(isOriginalGift))
                    {
                        throw new ServiceException("原始产品类型未知，无法进行补充提货。");
                    }

                    // 获取原始订单该产品的当前剩余未提货数量
                    // 1. 获取所有与该订单相关的提货/回款记录
                    HmSaleOrderPickUpBo hmSaleOrderPickUpBo = new HmSaleOrderPickUpBo();
                    hmSaleOrderPickUpBo.setSaleOrderId(requestBo.getOrderId());
                    hmSaleOrderPickUpBo.setStatus(PickUpStatusEnum.NORMAL.getCode()); // 只考虑正常状态的记录
                    List<HmSaleOrderPickUpVo> hmSaleOrderPickUpVos = queryList(hmSaleOrderPickUpBo); // 调用当前Service的queryList方法
                    // 通过 OrderProductCalculator 计算原始订单原始产品的实时剩余数量
                    OrderProductQuantities originalProductQuantities = orderProductCalculator.calculate(saleOrder, item.getOriginalProductId(), hmSaleOrderPickUpVos);
                    BigDecimal currentOriginalSurplusNum = originalProductQuantities.getSurplusQuantity();

                    // 校验补充数量不能大于原始未提数量
                    if (item.getQuantity().compareTo(currentOriginalSurplusNum) > 0)
                    {
                        throw new ServiceException(String.format("补充数量[%d]不能大于原始产品[%s]的剩余未提数量[%d]。", item.getQuantity(), originalProductVo.getProductName(), currentOriginalSurplusNum));
                    }

                    HmSupplementaryPickupRecordBo supplementaryBo = new HmSupplementaryPickupRecordBo();
                    supplementaryBo.setOriginalSaleId(requestBo.getOrderId());
                    supplementaryBo.setOriginalProductId(item.getOriginalProductId());
                    supplementaryBo.setOriginalProductName(originalProductVo.getProductName());
                    supplementaryBo.setOriginalUnfulfilledQuantity(currentOriginalSurplusNum); // 记录补充时的原始剩余量
                    supplementaryBo.setSupplementaryProductId(item.getProductId());
                    supplementaryBo.setSupplementaryProductName(productVo.getProductName());
                    supplementaryBo.setSupplementaryQuantity(item.getQuantity());
                    supplementaryBo.setPickupTime(new Date());
                    supplementaryBo.setPickupDeptId(requestBo.getPickupDeptId() != null ? requestBo.getPickupDeptId() : operatorDeptId); // 优先使用请求中的店铺ID，否则使用操作人店铺
                    supplementaryBo.setPickupDeptName(deptService.selectDeptById(supplementaryBo.getPickupDeptId()).getDeptName());
                    supplementaryBo.setOperatorId(operatorId);
                    supplementaryBo.setOperatorName(operatorName);
                    supplementaryBo.setReason(requestBo.getReason()); // 补充原因
                    supplementaryBo.setProofFileList(requestBo.getAttachments()); // 文件列表

                    supplementaryBo.setProofFiles(file); // 存储为字符串

                    supplementaryPickupRecordService.insertByBo(supplementaryBo);

                }
                else
                {
                    throw new ServiceException("无效的提货类型: " + requestBo.getType());
                }
            }
            catch (Exception e)
            {
                allSuccess = false;
                // 记录详细错误日志
                System.err.println("处理提货项失败：订单ID=" + requestBo.getOrderId() + ", 产品ID=" + item.getProductId() + ", 错误信息=" + e.getMessage());
                // 可以选择抛出第一个遇到的异常，或者收集所有错误信息
                throw e; // 重新抛出，让事务回滚
            }
        }
        return allSuccess;
    }

    /**
     * 新增销售订单提货、回款
     *
     * @param bo 销售订单提货、回款
     *
     * @return 是否新增成功
     */
    @Override
    public Boolean insert(HmSaleOrderPickUpBo bo)
    {
        HmSaleOrderPickUp add = MapstructUtils.convert(bo, HmSaleOrderPickUp.class);
        baseMapper.insert(add);
        return false;
    }

    /**
     * 修改销售订单提货、回款
     *
     * @param bo 销售订单提货、回款
     *
     * @return 是否修改成功
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateByBo(HmSaleOrderPickUpBo bo)
    {
        // 1. 获取原始的提货记录，判断是正常提货还是补充提货
        HmSaleOrderPickUpVo originalRecord = null;
        if (Boolean.TRUE.equals(bo.getIsSupplementaryPickup())) {
            // 尝试从补充提货记录表中查询
            HmSupplementaryPickupRecordVo supplementaryRecord = supplementaryPickupRecordService.queryById(bo.getPickUpId());
            if (supplementaryRecord != null) {
                // 将补充提货记录映射到 HmSaleOrderPickUpVo
                originalRecord = new HmSaleOrderPickUpVo();
                originalRecord.setPickUpId(supplementaryRecord.getSupplementaryPickupId());
                originalRecord.setSaleOrderId(supplementaryRecord.getOriginalSaleId());
                originalRecord.setSaleProductId(supplementaryRecord.getSupplementaryProductId()); // 补充提货的产品ID
                originalRecord.setPickUpNum(supplementaryRecord.getSupplementaryQuantity());
                originalRecord.setPickUpTime(supplementaryRecord.getPickupTime());
                originalRecord.setFile(supplementaryRecord.getProofFiles());
                originalRecord.setStatus(supplementaryRecord.getStatus());
                originalRecord.setRemark(supplementaryRecord.getReason());
                originalRecord.setIsSupplementaryPickup(true); // 明确标记
                // productType 需要根据 supplementaryProductId 再次查询产品类型
                Boolean isCp = hmProductService.isCommercialProduct(supplementaryRecord.getSupplementaryProductId());
                Boolean isZp = hmProductService.isGiftProduct(supplementaryRecord.getSupplementaryProductId());
                if (Boolean.TRUE.equals(isCp)) originalRecord.setProductType("CP");
                else if (Boolean.TRUE.equals(isZp)) originalRecord.setProductType("ZP");
            }
        } else {
            // 尝试从正常提货/回款记录表中查询
            originalRecord = baseMapper.selectVoById(bo.getPickUpId());
            if (originalRecord != null) {
                originalRecord.setIsSupplementaryPickup(false); // 明确标记
            }
        }

        if (originalRecord == null) {
            throw new ServiceException("要作废的提货/补充提货记录不存在。");
        }
        HmSaleOrderPickUp update = MapstructUtils.convert(bo, HmSaleOrderPickUp.class);
        // 2. 校验请求状态是否为作废【回款作废】
        if (!PickUpStatusEnum.CANCEL.getCode().equals(bo.getStatus())) {
            update.setStatus(PickUpStatusEnum.CANCEL.getCode());
            return baseMapper.updateById(update) > 0;
        }

        // --- 作废逻辑开始 ---
        // 如果是正常提货记录，直接更新其状态
        if (Boolean.FALSE.equals(originalRecord.getIsSupplementaryPickup())) {
            HmSaleOrderPickUp updateNormalPickup = MapstructUtils.convert(bo, HmSaleOrderPickUp.class); // 使用传入的bo进行更新
            updateNormalPickup.setStatus(PickUpStatusEnum.CANCEL.getCode()); // 确保状态设置为作废
            baseMapper.updateById(updateNormalPickup); // 更新 hm_sale_order_pick_up 表

            // ****** 正常提货作废的库存回填逻辑 ******
            // 获取产品类型信息
            Boolean isCommercialProduct = hmProductService.isCommercialProduct(originalRecord.getSaleProductId());
            Boolean isGiftProduct = hmProductService.isGiftProduct(originalRecord.getSaleProductId());

            if (StockTypeEnum.PICK_UP.getCode().equals(originalRecord.getPickUpType()) &&
                (Boolean.TRUE.equals(isCommercialProduct) || Boolean.TRUE.equals(isGiftProduct))) { // 提货作废只针对商品或赠品
                if (Boolean.TRUE.equals(isGiftProduct)) {
                    // 更新赠品的提货数量
                    HmSaleOrderGiftBo queryBo = new HmSaleOrderGiftBo();
                    queryBo.setSaleId(originalRecord.getSaleOrderId());
                    queryBo.setGiftProductId(String.valueOf(originalRecord.getSaleProductId()));
                    List<HmSaleOrderGiftVo> hmSaleOrderGiftVos = hmSaleOrderGiftService.queryList(queryBo);
                    if (hmSaleOrderGiftVos.size() > 0) {
                        HmSaleOrderGiftVo hmSaleOrderGiftVo = hmSaleOrderGiftVos.get(0);
                        hmSaleOrderGiftVo.setGiftUsedNum(hmSaleOrderGiftVo.getGiftUsedNum().subtract(originalRecord.getPickUpNum())); // 当前提货的数量
                        HmSaleOrderGiftBo updateGiftBo = new HmSaleOrderGiftBo();
                        BeanUtils.copyProperties(hmSaleOrderGiftVo, updateGiftBo);
                        hmSaleOrderGiftService.updateByBo(updateGiftBo);
                    }
                }
                // 提货数量回填到仓库
                HmSaleOrder saleOrder = hmSaleOrderMapper.selectById(originalRecord.getSaleOrderId()); // 查询销售订单获取店铺ID
                if (saleOrder == null) {
                    throw new ServiceException("关联的销售订单不存在，无法作废正常提货记录。");
                }
                HmStockBo hmStockBo = new HmStockBo();
                hmStockBo.setProductDept(saleOrder.getSaleDept()); // 提货店铺
                hmStockBo.setStockProductId(originalRecord.getSaleProductId()); // 提货产品
                List<HmStockVo> hmStockVos = hmStockService.queryList(hmStockBo);
                if (ObjectUtil.isNotEmpty(hmStockVos)) {
                    HmStockBo hmStockUpdateBo = new HmStockBo();
                    hmStockUpdateBo.setStockId(hmStockVos.get(0).getStockId());
                    hmStockUpdateBo.setStockProductId(hmStockVos.get(0).getStockProductId());
                    hmStockUpdateBo.setProductDept(hmStockVos.get(0).getProductDept());
                    hmStockUpdateBo.setStockNum(hmStockVos.get(0).getStockNum().add(originalRecord.getPickUpNum())); // 数量回填
                    hmStockUpdateBo.setSign(PickUpStatusEnum.CANCEL.getDescription()); // 标记作废
                    hmStockUpdateBo.setOrderId(saleOrder.getSaleId());
                    hmStockUpdateBo.setCustomerId(saleOrder.getCustomerId());
                    hmStockService.updateByBo(hmStockUpdateBo);
                } else {
                    // 如果作废时库存不存在，也需要新增库存
                    HmStockBo newStockBo = new HmStockBo();
                    newStockBo.setStockProductId(originalRecord.getSaleProductId());
                    newStockBo.setProductDept(saleOrder.getSaleDept());
                    newStockBo.setStockNum(originalRecord.getPickUpNum());
                    newStockBo.setRemark("正常提货作废，新增库存");
                    hmStockService.insertByBo(newStockBo);
                }

                // 记录库存变更
                HmStockChangeBo hmStockChangeBo = new HmStockChangeBo();
                HmStockVo updatedStock = hmStockService.queryByProductIdAndDeptId(originalRecord.getSaleProductId(), saleOrder.getSaleDept());
                hmStockChangeBo.setStockId(Optional.ofNullable(updatedStock).map(HmStockVo::getStockId).orElse(null)); // 可能为null
                hmStockChangeBo.setChangeType(StockChangeTypeEnum.PICK_UP_VOID.getCode()); // 提货作废入库
                hmStockChangeBo.setChangeInfo(StockChangeTypeEnum.PICK_UP_VOID.getDescription());
                hmStockChangeBo.setChangeNum(originalRecord.getPickUpNum()); // 回填数量
                hmStockChangeBo.setProductId(String.valueOf(originalRecord.getSaleProductId()));
                hmStockChangeBo.setChangeTime(new Date());
                hmStockChangeBo.setOrderId(originalRecord.getSaleOrderId());
                // 获取客户名称用于备注
                HmCustomerVo hmCustomerVo = customerMapper.selectVoById(saleOrder.getCustomerId());
                hmStockChangeBo.setRemark(String.format("订单[%s]提货作废,客户[%s]", originalRecord.getSaleOrderId(), hmCustomerVo != null ? hmCustomerVo.getCustomerName() : "未知客户"));
                hmStockChangeBo.setOperatorId(String.valueOf(LoginHelper.getUserId()));
                hmStockChangeBo.setOperator(LoginHelper.getLoginUser().getNickname());
                hmStockChangeService.insertByBo(hmStockChangeBo);
            }
        } else if (Boolean.TRUE.equals(originalRecord.getIsSupplementaryPickup())) {
            // ****** 补充提货作废逻辑 ******
            // 2a. 查询对应的 HmSupplementaryPickupRecord 记录
            HmSupplementaryPickupRecordVo supplementaryRecord = supplementaryPickupRecordService.queryById(originalRecord.getPickUpId());
            if (supplementaryRecord == null) {
                throw new ServiceException("关联的补充提货记录不存在，无法作废。");
            }

            // 2b. 修改 HmSupplementaryPickupRecord 的状态为 CANCELLED
            HmSupplementaryPickupRecordBo supplementaryUpdateBo = new HmSupplementaryPickupRecordBo();
            BeanUtils.copyProperties(supplementaryRecord, supplementaryUpdateBo); // 复制当前数据
            supplementaryUpdateBo.setSupplementaryPickupId(supplementaryRecord.getSupplementaryPickupId());
            supplementaryUpdateBo.setStatus(PickUpStatusEnum.CANCEL.getCode()); // 设置为作废状态
            supplementaryUpdateBo.setProofFiles(supplementaryRecord.getProofFiles());
            supplementaryPickupRecordService.updateByBo(supplementaryUpdateBo);

            // 2c. 将数量回填到该补充提货发生时的仓库 (补充产品所在仓库)
            HmStockVo hmStockVo = hmStockService.queryByProductIdAndDeptId(
                supplementaryRecord.getSupplementaryProductId(),
                supplementaryRecord.getPickupDeptId() // 补充提货时的仓库
            );
            if (ObjectUtil.isEmpty(hmStockVo)) {
                // 如果找不到库存，可能是数据异常，或者首次入库，需要新增库存记录
                HmStockBo newStockBo = new HmStockBo();
                newStockBo.setStockProductId(supplementaryRecord.getSupplementaryProductId());
                newStockBo.setProductDept(supplementaryRecord.getPickupDeptId());
                newStockBo.setStockNum(supplementaryRecord.getSupplementaryQuantity());
                newStockBo.setRemark("补充提货作废，新增库存");
                hmStockService.insertByBo(newStockBo); // 假设 insertByBo 也能处理新增
            } else {
                HmStockBo hmStockUpdateBo = new HmStockBo();
                hmStockUpdateBo.setStockId(hmStockVo.getStockId());
                hmStockUpdateBo.setStockProductId(hmStockVo.getStockProductId());
                hmStockUpdateBo.setSign(PickUpStatusEnum.CANCEL.getDescription()); // 标记作废
                hmStockUpdateBo.setOrderId(originalRecord.getSaleOrderId());
                hmStockUpdateBo.setProductDept(hmStockVo.getProductDept());
                hmStockUpdateBo.setStockNum(hmStockVo.getStockNum().add(supplementaryRecord.getSupplementaryQuantity())); // 数量回填
                hmStockService.updateByBo(hmStockUpdateBo);
            }


            // 2d. 记录库存变更
            HmStockChangeBo hmStockChangeBo = new HmStockChangeBo();
            hmStockChangeBo.setStockId(Optional.ofNullable(hmStockVo).map(HmStockVo::getStockId).orElse(null)); // 可能为null，如果是新创建的库存
            hmStockChangeBo.setChangeType(StockChangeTypeEnum.SUPPLEMENTARY_PICKUP_VOID.getCode()); // 补充提货作废入库
            hmStockChangeBo.setChangeInfo(StockChangeTypeEnum.SUPPLEMENTARY_PICKUP_VOID.getDescription());
            hmStockChangeBo.setChangeNum(supplementaryRecord.getSupplementaryQuantity()); // 回填数量
            hmStockChangeBo.setProductId(String.valueOf(supplementaryRecord.getSupplementaryProductId()));
            hmStockChangeBo.setChangeTime(new Date());
            hmStockChangeBo.setOrderId(supplementaryRecord.getOriginalSaleId()); // 关联原始订单ID
            hmStockChangeBo.setRemark(String.format("补充提货作废: 订单[%s], 产品[%s], 数量[%d]",
                supplementaryRecord.getOriginalSaleId(), supplementaryRecord.getSupplementaryProductName(), supplementaryRecord.getSupplementaryQuantity()));
            hmStockChangeBo.setOperatorId(String.valueOf(LoginHelper.getUserId()));
            hmStockChangeBo.setOperator(LoginHelper.getLoginUser().getNickname());
            hmStockChangeService.insertByBo(hmStockChangeBo);

        } else {
            // 如果既不是提货也不是补充提货（例如回款作废），则直接更新其状态
            // 这部分保持原有逻辑，仅仅更新状态
//             HmSaleOrderPickUp update = MapstructUtils.convert(bo, HmSaleOrderPickUp.class); // 这一行在方法开头已经处理
//             baseMapper.updateById(update);
        }
        // 无论哪种作废，最终都需要更新 HmSaleOrderPickUp 记录的状态为作废
        // 如果是补充提货，这里更新的是 HmSaleOrderPickUp 表中映射的那条记录的状态
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 处理退货逻辑,处理退货单与提货单的关系。
     *
     * @param hmSaleOrderRefundBo 提货订单实体
     *
     * @throws IllegalArgumentException 如果验证失败
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean processReturnLogic(HmSaleOrderRefundBo hmSaleOrderRefundBo, String pickUpType)
    {
        HmSaleOrder order = hmSaleOrderMapper.selectById(hmSaleOrderRefundBo.getSaleId());
        LambdaQueryWrapper<HmSaleOrderPickUp> saleOrderLqw = Wrappers.<HmSaleOrderPickUp>lambdaQuery()
            .eq(HmSaleOrderPickUp::getSaleOrderId, hmSaleOrderRefundBo.getSaleId()).eq(HmSaleOrderPickUp::getPickUpType, pickUpType);
        if (OrderStatus.PICK_UP.getCode().equals(pickUpType))
        {
            saleOrderLqw.eq(HmSaleOrderPickUp::getSaleProductId, hmSaleOrderRefundBo.getSaleProductId());
        }
        // 获取当前客户购买当前提货商品的销售产品订单按订单日期升序排列
        List<HmSaleOrderPickUp> pickUps = baseMapper.selectList(saleOrderLqw);
        pickUps.sort(Comparator.comparing(HmSaleOrderPickUp::getPickUpTime));
        // 初始化已分配数量为0
        BigDecimal allocatedQuantity = BigDecimal.ZERO;

        // 遍历订单列表，按照先卖先出货的原则分配数量
        for (HmSaleOrderPickUp pick : pickUps)
        {
            BigDecimal remainingQuantity;
            // 已分配完剩余退货数量
            if (pickUpType.equals(OrderStatus.PICK_UP.getCode()))
            {
                remainingQuantity = hmSaleOrderRefundBo.getMainProductReturnPickedQty().subtract(allocatedQuantity);
            }
            else
            {
                remainingQuantity = hmSaleOrderRefundBo.getRefundAmount().subtract(allocatedQuantity);
            }

            // 如果剩余数量为0，说明已经分配完毕，退出循环
            if (remainingQuantity.compareTo(BigDecimal.ZERO) == 0)
            {
                break;
            }
            // 可分配数量
            BigDecimal orderQuantity = pick.getPickUpNum();
            // 分配给订单数量即提货数量
            BigDecimal allocateToOrder = orderQuantity.min(remainingQuantity);

            // 更新已分配数量
            allocatedQuantity = allocatedQuantity.add(allocateToOrder);

            HmSaleOrderPickUp hmSaleOrderPickUpNew = new HmSaleOrderPickUp();
            hmSaleOrderPickUpNew.setPickUpId(pick.getPickUpId());
            hmSaleOrderPickUpNew.setStatus(PickUpStatusEnum.RETURN.getCode());
            hmSaleOrderPickUpNew.setIsRefundRelated(Boolean.TRUE);
            hmSaleOrderPickUpNew.setRelatedRefundId(hmSaleOrderRefundBo.getRefundId());
            hmSaleOrderPickUpNew.setReturnNum(allocateToOrder);

            baseMapper.updateById(hmSaleOrderPickUpNew);

        }

        return true;
    }

    /**
     * 处理提货逻辑，确保提货时仓库库存满足要求。
     *
     * @param hmSaleOrderPickUp 提货订单实体
     *
     * @throws IllegalArgumentException 如果验证失败
     */
    @Transactional(rollbackFor = Exception.class)
    protected Boolean handlePickUpLogic(HmSaleOrderPickUp hmSaleOrderPickUp)
    {

        // 根据订单id查询客户id
        //        HmSaleOrder hmSaleOrder = hmSaleOrderMapper.selectById(hmSaleOrderPickUp.getSaleOrderId());
        LambdaQueryWrapper<HmSaleOrder> saleOrderLqw = Wrappers.<HmSaleOrder>lambdaQuery().eq(HmSaleOrder::getSaleId, hmSaleOrderPickUp.getSaleOrderId());

        // 获取产品类型信息
        Boolean isCommercialProduct = hmProductService.isCommercialProduct(hmSaleOrderPickUp.getSaleProductId());
        Boolean isGiftProduct = hmProductService.isGiftProduct(hmSaleOrderPickUp.getSaleProductId());

        // 校验产品是否是商品或赠品
        if (Boolean.FALSE.equals(isCommercialProduct) && Boolean.FALSE.equals(isGiftProduct))
        {
            throw new IllegalArgumentException("提货失败，产品ID: " + hmSaleOrderPickUp.getSaleProductId() + " 既不是商品产品也不是赠品产品。");
        }

        // 获取当前客户购买当前提货商品的销售产品订单按订单日期升序排列
        List<HmSaleOrder> saleOrders = hmSaleOrderMapper.selectList(saleOrderLqw);
        saleOrders.sort(Comparator.comparing(HmSaleOrder::getSaleOrderTime));
        HmSaleOrder hmSaleOrder = saleOrders.get(0); // 假设第一个订单是需要处理的订单

        // 初始化已分配数量为0
        BigDecimal allocatedQuantity = BigDecimal.ZERO;

        // 遍历订单列表，按照先卖先出货的原则分配数量
        for (HmSaleOrder order : saleOrders)
        {
            // 已分配完剩余提货数量
            BigDecimal remainingQuantity = hmSaleOrderPickUp.getPickUpNum().subtract(allocatedQuantity);

            // 如果剩余数量为0，说明已经分配完毕，退出循环
            if (remainingQuantity.compareTo(BigDecimal.ZERO) == 0)
            {
                break;
            }
            // 查询当前订单的可分配额度
            HmSaleOrderVo convert = MapstructUtils.convert(order, HmSaleOrderVo.class);
            if (convert != null)
            {
                CalculateData(convert, hmSaleOrderPickUp.getPickUpType(), hmSaleOrderPickUp.getSaleProductId(), Boolean.TRUE.equals(isGiftProduct)); // 传递 isGiftProduct
                // 计算当前订单可以分配的数量
                BigDecimal orderQuantity = convert.getSurplusNum();
                // 分配给订单数量即提货数量
                BigDecimal allocateToOrder = orderQuantity.min(remainingQuantity);

                // 检查对应商品所在门店的仓库库存是否满足提货要求
                if (!isInventorySufficient(hmSaleOrderPickUp.getSaleProductId(), order.getSaleDept(), allocateToOrder))
                {
                    throw new IllegalArgumentException("仓库库存不足，无法满足提货要求");
                }

                // 更新已分配数量
                allocatedQuantity = allocatedQuantity.add(allocateToOrder);

                HmSaleOrderPickUp hmSaleOrderPickUpNew = new HmSaleOrderPickUp();
                hmSaleOrderPickUpNew.setSaleOrderId(convert.getSaleId());
                hmSaleOrderPickUpNew.setPickUpType(OrderStatus.PICK_UP.getCode());
                // 根据实际产品类型设置 pickUpType
                if (Boolean.TRUE.equals(isCommercialProduct))
                {
                    hmSaleOrderPickUpNew.setProductType("CP");
                }
                else if (Boolean.TRUE.equals(isGiftProduct))
                {
                    hmSaleOrderPickUpNew.setProductType("ZP");
                }
                hmSaleOrderPickUpNew.setPickUpNum(allocateToOrder);
                hmSaleOrderPickUpNew.setSaleProductId(hmSaleOrderPickUp.getSaleProductId()); // 提货产品id
                hmSaleOrderPickUpNew.setFile(hmSaleOrderPickUp.getFile());
                hmSaleOrderPickUpNew.setPickUpTime(new Date());
                if (Boolean.TRUE.equals(isGiftProduct))
                {
                    hmSaleOrderPickUpNew.setRemark("赠品提货");
                    // 更新赠品的提货数量
                    HmSaleOrderGiftBo queryBo = new HmSaleOrderGiftBo();
                    queryBo.setSaleId(convert.getSaleId());
                    queryBo.setGiftProductId(String.valueOf(hmSaleOrderPickUp.getSaleProductId()));
                    List<HmSaleOrderGiftVo> hmSaleOrderGiftVos = hmSaleOrderGiftService.queryList(queryBo);
                    if (hmSaleOrderGiftVos.size() > 0)
                    {
                        HmSaleOrderGiftVo hmSaleOrderGiftVo = hmSaleOrderGiftVos.get(0);
                        hmSaleOrderGiftVo.setGiftUsedNum(hmSaleOrderGiftVo.getGiftUsedNum().add(allocateToOrder)); // 当前提货的数量
                        HmSaleOrderGiftBo updateBo = new HmSaleOrderGiftBo();
                        BeanUtils.copyProperties(hmSaleOrderGiftVo, updateBo);
                        hmSaleOrderGiftService.updateByBo(updateBo);
                    }
                }
                else
                {
                    hmSaleOrderPickUpNew.setRemark("先卖先出提货");
                }
                baseMapper.insert(hmSaleOrderPickUpNew);
            }
            else
            {
                throw new IllegalArgumentException("数量分配异常");
            }

        }

        // 如果分配完毕后，已分配数量不等于提货订单的数量，抛出异常
        if (allocatedQuantity.compareTo(hmSaleOrderPickUp.getPickUpNum()) != 0)
        {
            throw new IllegalArgumentException("数量分配异常," + "本产品可提数量为:" + allocatedQuantity);
        }
        else
        {
            // 更新库存
            HmStockVo hmStockVo = hmStockService.queryByProductIdAndDeptId(hmSaleOrderPickUp.getSaleProductId(), hmSaleOrder.getSaleDept());
            HmStockBo hmStockBo = new HmStockBo();
            // 库存数量
            hmStockBo.setStockNum(hmStockVo.getStockNum().subtract(allocatedQuantity));
            // 更新的库存id
            hmStockBo.setStockId(hmStockVo.getStockId());
            hmStockService.pickUpUpdateByBo(hmStockBo);

            // 提货变更记录
            HmStockChangeBo hmStockChangeBo = new HmStockChangeBo();
            hmStockChangeBo.setStockId(hmStockBo.getStockId()); // 库存id
            hmStockChangeBo.setChangeType(StockChangeTypeEnum.PICK_UP.getCode()); // 提货
            hmStockChangeBo.setChangeInfo(StockChangeTypeEnum.PICK_UP.getDescription());
            hmStockChangeBo.setChangeNum(allocatedQuantity);// 变更数量
            hmStockChangeBo.setProductId(String.valueOf(hmSaleOrderPickUp.getSaleProductId()));
            hmStockChangeBo.setChangeTime(new Date()); // 变更时间
            hmStockChangeBo.setOrderId(hmSaleOrder.getSaleId()); //提货的订单ID
            hmStockChangeBo.setRemark(String.format("订单:%s,%s:%s件", hmSaleOrder.getSaleId(), StockChangeTypeEnum.PICK_UP.getDescription(), allocatedQuantity)); // 产品所属门店
            hmStockChangeBo.setOperatorId(hmSaleOrder.getCustomerId().toString()); // 客户id
            hmStockChangeBo.setProof(hmSaleOrderPickUp.getFile()); // 证明材料
            return hmStockChangeService.insertByBo(hmStockChangeBo);
        }
    }

    /**
     * 处理回款逻辑，确保回款按照先卖先回款的原则进行。
     *
     * @param hmSaleOrderPickUp 回款订单实体
     *
     * @throws IllegalArgumentException 如果验证失败
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean handlePaymentLogic(HmSaleOrderPickUpBo hmSaleOrderPickUp)
    {
        // 根据订单id查询客户id
        //        HmSaleOrder hmSaleOrder = hmSaleOrderMapper.selectById(hmSaleOrderPickUp.getSaleOrderId());
        //        // 获取当前客户的销售产品订单列表，按订单日期升序排列
        //        List<HmSaleOrder> saleOrders = hmSaleOrderMapper.selectList(Wrappers.<HmSaleOrder>lambdaQuery()
        //            .eq(HmSaleOrder::getCustomerId, hmSaleOrder.getCustomerId()).eq(HmSaleOrder::getSaleProductId, hmSaleOrder.getSaleProductId()));
        List<HmSaleOrder> saleOrders = hmSaleOrderMapper.selectList(Wrappers.<HmSaleOrder>lambdaQuery()
            .eq(HmSaleOrder::getSaleId, hmSaleOrderPickUp.getSaleOrderId()));
        HmSaleOrder hmSaleOrder = saleOrders.get(0);
        //        saleOrders.sort(Comparator.comparing(HmSaleOrder::getSaleOrderTime));
        // 计算总欠款金额

        BigDecimal totalDebt = saleOrders.stream().map(item ->
        {
            HmSaleOrderVo convert = MapstructUtils.convert(item, HmSaleOrderVo.class);
            CalculateData(convert, hmSaleOrderPickUp.getPickUpType(), hmSaleOrderPickUp.getSaleProductId(), false);
            return convert.getRefundSurplusNum();
        }).reduce(BigDecimal.ZERO, BigDecimal::add);

        // 如果当前提货订单的金额大于客户的总欠款金额，抛出异常
        if (hmSaleOrderPickUp.getPickUpNum().compareTo(totalDebt) > 0)
        {
            throw new IllegalArgumentException("回款金额不能大于客户的总欠款金额");
        }

        // 初始化已分配金额为0
        BigDecimal allocatedAmount = BigDecimal.ZERO;

        // 遍历订单列表，按照先卖先回款的原则分配金额
        for (HmSaleOrder order : saleOrders)
        {
            BigDecimal remainingAmount = hmSaleOrderPickUp.getPickUpNum().subtract(allocatedAmount);

            // 如果剩余金额为0，说明已经分配完毕，退出循环
            if (remainingAmount.compareTo(BigDecimal.ZERO) == 0)
            {
                break;
            }
            HmSaleOrderVo convert = MapstructUtils.convert(order, HmSaleOrderVo.class);
            CalculateData(convert, hmSaleOrderPickUp.getPickUpType(), hmSaleOrderPickUp.getSaleProductId(), false);
            // 计算当前订单可以分配的金额
            BigDecimal orderDebt = convert.getRefundSurplusNum();
            // 分配给订单金额
            BigDecimal allocateToOrder = orderDebt.min(remainingAmount);

            // 更新已分配金额
            allocatedAmount = allocatedAmount.add(allocateToOrder);

            // 新增回款订单
            HmSaleOrderPickUp hmSaleOrderPickUpNew = new HmSaleOrderPickUp();
            hmSaleOrderPickUpNew.setSaleOrderId(convert.getSaleId());
            hmSaleOrderPickUpNew.setPickUpType(OrderStatus.RETURN_MONEY.getCode());
            hmSaleOrderPickUpNew.setFile(hmSaleOrderPickUp.getFile());
            hmSaleOrderPickUpNew.setPickUpNum(allocateToOrder);
            hmSaleOrderPickUpNew.setPickUpTime(new Date());
            hmSaleOrderPickUpNew.setMethod(hmSaleOrderPickUp.getMethod());
            hmSaleOrderPickUpNew.setRemark("先卖先出回款");
            baseMapper.insert(hmSaleOrderPickUpNew);
        }

        // 如果分配完毕后，已分配金额不等于提货订单的金额，抛出异常
        if (allocatedAmount.compareTo(hmSaleOrderPickUp.getPickUpNum()) != 0)
        {
            throw new IllegalArgumentException("金额分配异常");
        }
        else
        {
            return true;
        }
    }

    /**
     * 检查对应商品所在门店的仓库库存是否满足提货要求。
     *
     * @param productId 商品ID
     * @param storeId   门店ID
     * @param quantity  需要提货的数量
     *
     * @return 如果库存充足返回true，否则返回false
     */
    private boolean isInventorySufficient(Long productId, Long storeId, BigDecimal quantity)
    {
        // 只有商品产品和赠品产品才需要检查库存
        Boolean isCommercialProduct = hmProductService.isCommercialProduct(productId);
        Boolean isGiftProduct = hmProductService.isGiftProduct(productId);

        if (Boolean.FALSE.equals(isCommercialProduct) && Boolean.FALSE.equals(isGiftProduct))
        {
            // 如果既不是商品也不是赠品，则可能不需要检查库存（例如服务类产品），或者根据业务规则抛出异常
            return true; // 假设不需要库存检查
        }

        // 查询对应商品所在门店的仓库库存
        HmStockVo hmStockVo = hmStockService.queryByProductIdAndDeptId(productId, storeId);
        if (ObjectUtil.isEmpty(hmStockVo))
        {
            return false;
        }
        BigDecimal inventory = hmStockVo.getStockNum();
        // 如果库存为null或不足，返回false
        if (inventory.compareTo(quantity) < 0)
        {
            return false;
        }

        // 库存充足，返回true
        return true;
    }

    /**
     * 校验并批量删除销售订单提货、回款信息
     *
     * @param ids     待删除的主键集合
     * @param isValid 是否进行有效性校验
     *
     * @return 是否删除成功
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid)
    {
        if (isValid)
        {
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteByIds(ids) > 0;
    }

    /**
     * 计算待提货、待回款
     *
     * @param saleId
     * @param saleNum
     * @param pickUpType
     * @param productId
     * @param isGiftProductFlag // 从 isZP 修改为 isGiftProductFlag
     */
    private void CalculateData(HmSaleOrderVo hmSaleOrderVo, String pickUpType, Long productId, boolean isGiftProductFlag)
    {
        HmSaleOrderPickUpBo hmSaleOrderPickUpBo = new HmSaleOrderPickUpBo();
        hmSaleOrderPickUpBo.setSaleOrderId(hmSaleOrderVo.getSaleId());
        hmSaleOrderPickUpBo.setStatus(PickUpStatusEnum.NORMAL.getCode());
        List<HmSaleOrderPickUpVo> hmSaleOrderPickUpVos = queryList(hmSaleOrderPickUpBo);
        // 2. 过滤pickUpType为1的提货记录数据,计算商品总提货数量
        if (OrderStatus.PICK_UP.getCode().equals(pickUpType))
        {
            if (isGiftProductFlag) // 如果是赠品产品
            {
                BigDecimal pickUpSum = Optional.ofNullable(hmSaleOrderPickUpVos).orElse(new ArrayList<>()).stream()
                    .filter(hmSaleOrderPickUpVo -> OrderStatus.PICK_UP.getCode().equals(hmSaleOrderPickUpVo.getPickUpType())) // 提货
                    .filter(hmSaleOrderPickUpVo -> hmSaleOrderPickUpVo.getSaleProductId().equals(productId))
                    .map(HmSaleOrderPickUpVo::getPickUpNum)
                    .reduce(BigDecimal.ZERO, BigDecimal::add); // 计算总提货数量

                hmSaleOrderVo.setPickUpNum(Convert.toBigDecimal(pickUpSum, new BigDecimal(0))); // 已提货数量
                // 查询该赠品在该订单下的销售数量为多少
                HmSaleOrderGiftBo hmSaleOrderGiftBo = new HmSaleOrderGiftBo();
                hmSaleOrderGiftBo.setSaleId(hmSaleOrderVo.getSaleId());
                hmSaleOrderGiftBo.setGiftProductId(String.valueOf(productId));
                List<HmSaleOrderGiftVo> hmSaleOrderGiftVos = hmSaleOrderGiftService.queryList(hmSaleOrderGiftBo);
                BigDecimal giftNum = hmSaleOrderGiftVos.stream().map(HmSaleOrderGiftVo::getGiftNum).reduce(BigDecimal.ZERO, BigDecimal::add); // 总赠送数量
                hmSaleOrderVo.setSurplusNum(Convert.toBigDecimal(giftNum, new BigDecimal(0)).subtract(Convert.toBigDecimal(pickUpSum, new BigDecimal(0)))); // 剩余提货数量
            }
            else // 商品产品
            {
                double pickUpSum = Optional.ofNullable(hmSaleOrderPickUpVos).orElse(new ArrayList<>()).stream()
                    .filter(hmSaleOrderPickUpVo -> OrderStatus.PICK_UP.getCode().equals(hmSaleOrderPickUpVo.getPickUpType())) // 提货
                    .filter(hmSaleOrderPickUpVo -> hmSaleOrderPickUpVo.getSaleProductId().equals(hmSaleOrderVo.getSaleProductId()))
                    .flatMapToDouble(hmSaleOrderPickUpVo -> DoubleStream.of(hmSaleOrderPickUpVo.getPickUpNum().doubleValue())).sum();
                hmSaleOrderVo.setPickUpNum(Convert.toBigDecimal(pickUpSum, new BigDecimal(0))); // 已提货数量
                hmSaleOrderVo.setSurplusNum(Convert.toBigDecimal(hmSaleOrderVo.getSaleNum(), new BigDecimal(0)).subtract(Convert.toBigDecimal(pickUpSum, new BigDecimal(0)))); // 剩余提货数量
            }

        }
        else if (OrderStatus.RETURN_MONEY.getCode().equals(pickUpType))
        {
            // 3. 过滤pickUpType为0的回款记录数据,计算商品已回款金额
            double surplusNum = Optional.ofNullable(hmSaleOrderPickUpVos).orElse(new ArrayList<>()).stream()
                .filter(hmSaleOrderPickUpVo -> OrderStatus.RETURN_MONEY.getCode().equals(hmSaleOrderPickUpVo.getPickUpType()))
                .flatMapToDouble(hmSaleOrderPickUpVo -> DoubleStream.of(hmSaleOrderPickUpVo.getPickUpNum().doubleValue())).sum();

            hmSaleOrderVo.setReturnAmount(Convert.toBigDecimal(surplusNum, new BigDecimal(0))); // 已回款金额

            hmSaleOrderVo.setRefundSurplusNum(hmSaleOrderVo.getSaleAmount().subtract(Convert.toBigDecimal(surplusNum, new BigDecimal(0)))); // 剩余未回款金额
        }
    }

}
